package com.ahdms.es.gm.algorithm;

import com.ahdms.es.util.SM2Utils;
import org.bouncycastle.crypto.CipherParameters;
import org.bouncycastle.crypto.params.ECKeyParameters;
import org.bouncycastle.crypto.params.ECPublicKeyParameters;
import org.bouncycastle.math.ec.ECPoint;

import java.math.BigInteger;

public class SM2Signer {

    private ECKeyParameters keyParam;

    public void init(CipherParameters param) {
        this.keyParam = (ECPublicKeyParameters) param;
    }

    public BigInteger[] generateSignature(byte[] message) {
        return null;
    }

    public boolean verifySignature(byte[] message, BigInteger r, BigInteger s) {
        ECPublicKeyParameters pubKey = (ECPublicKeyParameters) keyParam;
        BigInteger n = pubKey.getParameters().getN();
        ECPoint G = pubKey.getParameters().getG();
        ECPoint P_A = pubKey.getQ();

        if (!SM2Utils.validSM2BigInteger(r) || !SM2Utils.validSM2BigInteger(s)) {
            return false;
        }

        BigInteger e = new BigInteger(1, message);
        BigInteger t = r.add(s).mod(n);
        if (t.equals(BigInteger.ZERO)) {
            return false;
        } else {
            ECPoint x1y1 = G.multiply(s).add(P_A.multiply(t));
            BigInteger R = e.add(x1y1.normalize().getXCoord().toBigInteger()).mod(n);
            return R.equals(r);
        }
    }

}
